"Initialize the blue button pop-up menu and corresponding array of messages for the receiver. Refer to class method initialize in StandardSystemController for up-to-date menu items."
"If the user has changed the more important message selector for the icon (which it is depends on the icon), then use the new selector as the label; otherwise, do nothing."
model getYellowMenu: ''method'' suffix: '' categories''
comment: The get-menu message (if not nil) is used by the window to ask the model for the yellow-button pop-up menu to be used.
when used: This message is sent to the model each time the user presses the yellow button while in this window. The entries in the menu may be different each time.
restrictions: For non-nil messages, the receiver must be ''model''. Any number of constant parameters can be specified; nil, true, and false are permitted. The result returned must be either an action menu or nil.
action menus: For text windows (only), the action menu normally includes the standard text editing selectors ''again, undo, copySelection, cut, paste, accept, cancel'' in addition to user selectors. The user selectors can either have no parameters or two parameters (the current text and the controller). When selected, the editing selectors are handled automatically by the text window; the user selectors are sent as messages to the model.
warning: The text object passed in the first of two parameter selectors (e.g., mine2:and: above) is the actual text used by the text window. This text could be stored in the model. However, subsequent destructive changes by the window will cause it to change. If the stored version is to be left intact, care should be taken to store a copy."'
comment: A view name can be used to access the view when pre-opening or post-closing an extended standard system view.
restrictions: A view name must either be nil or a symbol.
additional information: For a more detailed explanation, see comment in the external interface for the master window; i.e., get the yellow-button pop-up menu when no icons are selected and choose the external interface entry."'
comment: An update symbol can be used by the model to cause all (and only) windows with the corresponding update symbol to update themselves. To do this, the model sends the message ''self changed: #updateSymbol''.
restrictions: An update symbol must either be nil or a symbol.
how windows update: The exact manner depends on the kind of window; e.g., a text window obtains new text from the model, a menu window obtains a new permanent menu and a new selection from the model, a switch window asks the model if it is on, and a picture window with dynamic pictures asks the model for a new picture.
illustration: Suppose a number of switches select shades (white, gray, black) by sending appropriate ''switchColor: aSymbol'' messages to the model. Moreover, suppose a text window is intended to display the current shade and a menu window is intended to display all three entries with the appropriate one selected. Communication between the switches and the text and menu window can be achieved by providing the following methods in the model.
switchColor: aSymbol
""This is a switch window method""
currentColor _ aSymbol.
self changed: #color
getText
""This is a text window method""
^currentColor asText
getMenu
""This is a menu window method""
^#(white gray black)
getMenuSelection
""This is a menu window method""
^currentColor
The ''self changed: #shade'' message will cause all windows with update symbol ''shade'' to update themselves. In this case, the text window uses its getText message while the menu window uses its getMenu and getMenuSelection messages. Alternate names for getText, getMenu, and getMenuSelection can be specified by the window designer."'
"Returns an array containing the text; either the elements of a message or nil for legal text (the latter only if nilLegal is true); #() is returned if an error is reported. The message elements have the form <receiver selector> or <receiver keyword1: constant1 keyword2: constant2 ...>."
"Returns an array containing the text; either a symbol (name), a string, or nil for legal text (the former only if symbolNeeded is true); #() is returned if an error is reported."
"Returns an array containing the text objects with symbols #nil, #true, and #false translated to the corresponding constants. If an error is detected, a message is generated and an empty array is returned. Note: later processing is unable to differentiate between symbols like '#hello' and variables like 'hello' because the evaluation step has eliminated the distinction."
An external window is used to reference and obtain a previously constructed extended view. This extended view replaces the external window at open time. An external window references its extended view via one message:
(1) getView to obtain an extended view.
An extended view may constructed in the WindowMaker by specifying that it be a subview (as opposed to a top view) in the external interface for the master window.'
runs: (RunArray
runs: #(4 15 405 )
values: #(1 2 1 ))!
defaultGetView
^Text
string: '
Object getView
"other examples:
FormLibrarian subView
Object getView: #blueButton version: 2
comment: Permits an externally constructed extended view to be integrated with the current view. The extended view replaces this external view at open time.
restrictions: The receiver must be a class name. Any number of constant parameters can be specified; nil, true, and false are permitted. An extended view must be returned.
constructing extended views: An extended view can be constructed by the window maker by specifying a subview (as opposed to top view) in the interface at the top level (master window); i.e., by not selecting any icons, choosing the external interface entry in the yellow pop-up menu, and setting the topView option to false."'
"Since this view does not scale, scale the subviews."
subViews do: [:anIcon | anIcon scaleBy: scale]!
zoomIn
self scaleBy: 1.1@1.1.
self displayView!
zoomOut
self scaleBy: 0.9@0.9.
self displayView! !
!WindowMakerMasterIcon methodsFor: 'displaying'!
computeDisplayTransformation
"Ensure that (1) this view does not scale and (2) the window center maps to the display box center. One solution is to ensure that the window center is 0@0 and the same as the display box; a side-benefit is that the sub-icons need never be moved since they are always positioned in a window that appears to be fixed."
| box |
"First, compute the normal way (need the display box) and then change it."
"Creates a form with the existing icons and then displays the form. This prevents the user from seeing the icons individually displayed one after the other."
A master window is a window that contains all the subwindows obtained from the window maker. A method can be generated that produces the corresponding view. Two varieties exist:
(1) an extended standard system view (a standalone top view).
(2) an extended view (a subview).
Either one of these can incorporate a separately generated subview by constructing an external window that references it. At open time, such external windows are replaced by the corresponding extended view. See external windows for more details.
options: The topView option specifies whether a top view or subview is desired. The title, preOpen, and postOpen options apply only to top views. The title provides the tab at the top of the window (e.g., ''Master Window Interface'' for this window); a nil title implies no tab at all. The preOpen and postClose options (when not nil) are messages sent to the model immediately before the window is opened and immediately after it is closed respectively.
opening windows: A top window is opened by providing either an encoding of the window which is compact or an extended standard system view which is lengthy but much faster. The method construction option gives you a choice of the two. In either case, the window maker uses this view or creates one if necessary and distributes the model to all subviews. A preOpen message (if it exists) is then sent to the model.
WindowMaker open: encodedWindowOrView on: aModel
preOpen and postClose messages: These messages permit the model to find and store (by name) subviews useful for the application and to redistribute (or change) the models associated with them. The preOpen and postClose messages include the extended systandard system view as a parameter. A preOpen message might be used (1) to record, for example, an error message subwindow called ''error'' for later use (assuming such a window was part of the master window) or (2) to initialize some of the subwindows with models other than itself; this might be needed for setting up the model for an external window. A postClose message might be used to perform final post-processing; e.g., if a window provides alignment options, closing the window might be the signal to actually perform the alignment. An example preOpen method is
Method viewNamed: retrieves the subview with the specified name. Method models: recursively replaces nil models by the parameter for all subviews; non-nil models are unmodified and stop the recursion. Method resetModels recursively sets all non-nil models to nil in the same way.'
model closeup: #anExtendedStandardSystemView forPane: 2
comment: The post-close message (if not nil) is sent to the model immediately after the window (view) is closed. The view replaces the first parameter.
restrictions: For non-nil messages, the receiver must be ''model''. One or more constant parameters can be specified; nil, true, and false are permitted. The result returned is not used."'
model preInitialize: #anExtendedStandardSystemView
model setup: #anExtendedStandardSystemView forPane: 2
comment: The pre-open message (if not nil) is sent to the model immediately before the window (view) is opened. The view replaces the first parameter.
restrictions: For non-nil messages, the receiver must be ''model''. One or more constant parameters can be specified; nil, true, and false are permitted. The result returned is not used."'
"Moreover, the center of the new display box must be at the center of the view. This can be achieved only if the subviews are offset by the same amount."
offset _ view displayBox center - newDisplayBox center.
newDisplayBox moveBy: offset. "Move its center to the old one."
"Determines the superview's display box from a new (arbitrary) display box for the view. Note: if t maps this view's viewport to aViewDisplayBox, then t will also map the superview's window to its new display box."
"For choosing multiple selections, draw a rectangle that tracks the mouse. Drawing is achieved by repeatedly erasing the previous rectangle and redrawing the new. By using rule reverse for all drawing, we guarantee that all lines drawn can be undone."
"If the shift key is down, a new selection is added and an old selection is removed. If the shift key is up, new selections replace existing selections; old selections are moved. If nothing is selected, all old selections are removed."
model changeMenuSelection: #aSelection for: ''method'' suffix: '' category''
comment: The change-menu-selection message is used by the menu window to inform the model that a new selection has been made. This selection is provided in the first parameter; either a getMenu array entry if a selection has been made or nil if a deselection has occurred.
when used: This message is sent to the model whenever the user interactively modifies the window.
restrictions: The receiver must be ''model''. One or more constant parameters can be specified; nil, true, and false are permitted. The first parameter (#aSelection above) is replaced by the actual selection object (if an actual selection was made) or nil (if a deselection was made) before the message is sent. The result returned is ignored."'
A menu window communicates with its model via messages
(1) getMenu to obtain the permanent menu from the model
(an array of objects with distinct print strings).
(2) getSelection to obtain the menu selection to be displayed from the model
(one of the objects in the above array or nil).
(3) changeSelection to tell the model of a menu selection change
(one of the objects in the above array or nil).
(4) getYellowMenu to obtain the yellow button pop-up menu from the model
(an action menu).
updateSymbol comments: If the model changes its version of the permanent menu or the menu selection and the window should reflect the model''s version, the model should send a ''self changed: #updateSymbol'' message. This could be done anywhere including in the above four methods.'
model getMenuArrayFor: ''method'' suffix: '' category''
comment: The get-menu-array message is used by the menu window to ask the model for the permanent menu entries to be displayed.
when used: This message is sent to the model (1) when the window is initially displayed and (2) each time it reacts to a ''self changed: #updateSymbol'' message sent by the model.
restrictions: The receiver must be ''model''. Any number of constant parameters can be specified; nil, true, and false are permitted. The result returned must be an array of arbitrary objects with distinct print strings; an ordered collection instead of an array, for example, is not permitted."'
model getMenuSelectionFor: ''method'' suffix: '' category''
comment: The get-selection message is used by the menu window to ask the model for the current selection. If a selection has been made, the corresponding getMenu array element is returned; otherwise, nil.
when used: This message is sent to the model (1) when the window is initially displayed and (2) each time it reacts to a ''self changed: #updateSymbol'' message sent by the model.
restrictions: The receiver must be ''model''. Any number of constant parameters can be specified; nil, true, and false are permitted. The result returned must be one of the objects in the permanent menu array (the one selected) or nil (for no selection)."'
"Construct a new label from the current settings; i.e., from the switch path name or picture string. The icon display box may change if the label changes size."
| newLabel |
newLabel _ self getLabel.
sizeLocked ifTrue: [
sizeLocked _ false.
"Avoid the following method since it computes the display box (works only if this icon has a superview); e.g., after initialization."
Normally, a picture window contains a label (picture) that remains unchanged throughout its existence. However, there may be situations where this label may have to vary dynamically. For an example, see the form librarian editor. In that case, 2 additional pieces of information must be provided:
(1) #updateSymbol that identifies the window for changes,
(2) getLabel message to obtain a new display object; e.g., a form or a paragraph.
If the model changes in such a way that this picture window must be updated, it is sufficient for the model to execute "self changed: #updateSymbol".'
runs: (RunArray
runs: #(13 14 12 5 2 7 538 )
values: #(1 2 1 2 1 2 1 ))!
defaultGetLabel
^Text
string: '
nil
"other examples:
model getLabel
model getLabelFor: #firstName
comment: The get-label message (when not nil) is used by the window to ask the model for a new label (picture) to be displayed. This label must be nil or a display object such as a display text, a paragraph, or a form.
when used: This message is sent to the model (1) each time the window is displayed and (2) each time it reacts to a ''self changed: #updateSymbol'' message sent by the model.
aside: A non-nil get-label message is useful only if the window picture must change dynamically.
restrictions: The receiver for a non-nil get-label message must be ''model''. Any number of constant parameters can be specified; nil, true, and false are permitted. The result returned must be nil or a display object; e.g., a paragraph, display text, or form."'
A switch window communicates with its model via 2 messages
(1) isOn to ask the model if the switch is on (the switch status).
(2) switch to tell the model that the switch has been pressed.
updateSymbol comments: If the model changes the switch status and the window should reflect the model''s version, the model should send a ''self changed: #updateSymbol'' message. This could be done anywhere including in the above two methods.'
runs: (RunArray
runs: #(3 13 50 4 43 13 8 6 54 21 218 )
values: #(1 2 1 2 1 2 1 2 1 2 1 ))!
defaultIsOn
^Text
string: '
model isOn
"other examples:
model isColor: #blue
model isBorderSize: 1
comment: The is-on message is used by the switch window to ask the model if the switch is on.
when used: This message is sent to the model (1) when the switch window is initially displayed and (2) each time it reacts to a ''self changed: #updateSymbol'' message sent by the model.
restrictions: The receiver must be ''model''. Any number of constant parameters can be specified; nil, true, and false are permitted. The result returned must be a boolean: true to indicate the switch is down (depressed), false to indicate the switch is up (not depressed)."'
comment: The switch message is used by the switch window to tell the model that the switch has been pressed. The model will appropriately change its state; e.g., by setting one of its instance variables. The switch window subsequently asks the model (using the isOn message) to find out whether this caused the switch to turn on (the isOn message replies true) or off (the isOn message replies false).
when used: when the user interactively pushes the mouse button while in the switch window.
restrictions: The receiver must be ''model''. Any number of constant parameters can be specified; nil, true, and false are permitted. The result returned is ignored.
sample methods: If the methods for the above messages are implemented as follows, then the switch, turnOn, and turnOff methods will work as expected.
model changeVitaeTextTo: #aText for: #personnel version: #short
comment: The change-text message is used by the text window give the model updated text to be recorded. This text is provided in the first parameter.
when used: This message is sent to the model when the user accepts the text in the text window.
restrictions: The receiver must be ''model''. One or more constant parameters can be specified; nil, true, and false are permitted. The first parameter (#aText above) is replaced by the actual text before the message is sent. The result returned must be a boolean with the following interpretation: true - the text has been recorded, false - the text has not been recorded (it has been rejected). Typically, true is returned.
warning: The text object given to the model is the actual text used by the text window. Hence, the window may subsequently physically modify it. To ensure that the version maintained by the model is left intact, the changeText method should store a copy.
optional: Prior to sending a changeText message, the window always asks the model for permission by sending it a ''changeRequestFrom: aView'' message. The default inherited by all objects is to reply true if no other windows contain unaccepted modified text (interactive prompting occurs). If this default is not acceptable, the model will need to incorporate its own special version such as the following:
A text window communicates with its model via messages
(1) getText to obtain the text to be displayed from the model.
(2) changeText to provide the model with modified text.
(3) getMenu to obtain the yellow pop-up menu from the model.
updateSymbol comments: If the model changes its copy of the text and the window should reflect the model''s version, the model should send a ''self changed: #updateSymbol'' message. This could be done anywhere including in the above three methods.
text comments: The getText and changeText messages respectively obtain and provide a text object; a string is not allowed. Moreover, the text object is destructively modified by the view. If the model''s version of the text is to be separate from the view''s version, a copy should be saved or provided respectively.'
runs: (RunArray
runs: #(3 11 48 7 57 10 47 7 51 21 225 13 301)
values: #(1 2 1 2 1 2 1 2 1 2 1 2 1))!
defaultGetText
^Text
string: '
model getText
"other examples:
model getNameTextFor: #manager
model getVitaeTextFor: #personnel version: #short
comment: The get-text message is used by the text window to ask the model for the text to be displayed.
when used: This message is sent to the model (1) when the window is initially displayed and (2) each time it reacts to a ''self changed: #updateSymbol'' message sent by the model.
restrictions: The receiver must be ''model''. Any number of constant parameters can be specified; nil, true, and false are permitted. The result returned must be a text object; a string will not suffice.
warning: The text object given to the text window is physically modified. To ensure that the version maintained by the model is left intact, the getText method should return a copy."'